package hamaster.jpbc.sys;

import static hamaster.jpbc.pbc.io.SimpleIDFileIOImpl.PERSONAL_PREFIX;
import static hamaster.jpbc.pbc.io.SimpleIDFileIOImpl.PRIVATE_PREFIX;
import static hamaster.jpbc.pbc.io.SimpleIDFileIOImpl.PUBLIC_PREFIX;
import hamaster.jpbc.pbc.PBC;
import hamaster.jpbc.pbc.PBCDriver;
import hamaster.jpbc.pbc.PrivateKey;
import hamaster.jpbc.pbc.PublicParameter;
import hamaster.jpbc.pbs.PBS;
import hamaster.jpbc.pbs.PersonalParameter;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.plaf.jpbc.pairing.CurveParams;

import java.io.IOException;
import java.io.Serializable;
import java.util.Properties;

public class IBCConfig implements Serializable {
	private static final long serialVersionUID = 8402144039877592829L;

	public final static String SYSTEM_MASTER_KEY = "alpha";
	public final static String SIGNATURE_MASTER_KEY = "sign";

	private PublicParameter parameter;

	private Element alpha;

	private Element signatureKey;

	private PersonalParameter signParameter;

	private PrivateKey privateKey;

	public IBCConfig() {
		alpha = null;
		parameter = null;
	}

	public PublicParameter publicParameter() {
		return parameter;
	}

	public Element systemKey() {
		return alpha;
	}

	public Element systemSignatureKey() {
		return signatureKey;
	}

	public PersonalParameter signatureParameter () {
		return signParameter;
	}

	public PrivateKey privateKey() {
		return privateKey;
	}

	public void setCurvePath(String curvePath) {
		CurveParams params = new CurveParams();
		try {
			params.load(getClass().getResourceAsStream("/" + curvePath));
			PBC.instance(params).getPairing().getZr().newRandomElement();
		} catch (Exception e) {
		}
	}

	public void setConfigPath(String configPath) {
		final Properties properties = new Properties();
		try {
			properties.load(getClass().getResourceAsStream("/" + configPath));
		} catch (IOException e) {
		}
		Thread t = new Thread() {
			@Override
			public void run() {
				PBC pbc = PBC.instance();
				for (;;) {
					// 等待PBC加载
					if (pbc != null) {
						PBS.instance(pbc);
						break;
					}
					try {
						sleep(10);
					} catch (InterruptedException e) {
					}
				}
				if (parameter == null) {
					parameter = new PublicParameter();
					parameter.setFromProperties(properties, PUBLIC_PREFIX);
				}
				if (alpha == null) {
					String mk = properties.getProperty(SYSTEM_MASTER_KEY);
					alpha = pbc.getPairing().getZr().newElement();
					alpha.setFromBytes(PBCDriver.unhex(mk));
				}
				if (signParameter == null) {
					signParameter = new PersonalParameter();
					signParameter.setFromProperties(properties, PERSONAL_PREFIX);
				}
				if (privateKey == null) {
					privateKey = new PrivateKey();
					privateKey.setFromProperties(properties, PRIVATE_PREFIX);
				}
				if (signatureKey == null) {
					String sk = properties.getProperty(SIGNATURE_MASTER_KEY);
					signatureKey = pbc.getPairing().getZr().newElement();
					signatureKey.setFromBytes(PBCDriver.unhex(sk));
				}
			}
		};
		t.start();
	}
}
